package com.sw.server;

import com.sw.servlet.HttpServlet;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.sw.server.handthreadpool.RequestProcess;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author sw
 * @project minicat
 * @description minicat 启动类
 * @date 2020/4/25 15:43
 */
public class Bootstrap {
    /**
     * 端口
     */
    private int port=8080;

    /**
     * minicat 启动需要初始化操作
     */
    public void start() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        //加载解析web.xml
        loadServlet();
        //定义线程池
        int corePoolSize=10;//线程池初始化大小
        int maximumPoolSize=50;//最大
        long keepAliveTime=10;
        TimeUnit unit=TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory=Executors.defaultThreadFactory();
        RejectedExecutionHandler handler=new  ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(corePoolSize,maximumPoolSize,
                keepAliveTime,unit,workQueue,threadFactory,handler);
        /**
         * 浏览器访问http://localhost:8080
         */
        try {
            ServerSocket serverSocket=new ServerSocket(port);
            System.out.println("minicat start port "+port);
            //阻塞循环
           /* while (true){
                Socket socket=serverSocket.accept() ;
                System.out.println("进来额");
                //存在socket 接收请求 获取输入
                OutputStream outputStream=socket.getOutputStream();
                String minicatStr="hello word minicat";
                String responseText=HttpProtocolUtil.getHttpHeader200(minicatStr.getBytes().length)+minicatStr;
                System.out.println(responseText);
                outputStream.write(responseText.getBytes());
                socket.close();
            }*/
            /**
             * 需求： 封装Request和Response对象 并返回html静态资源
             *
             */
           /* while (true){
                Socket socket=serverSocket.accept() ;
                InputStream inputStream = socket.getInputStream();
                //从输入流获取请求信息 IO模型 BIO
                int count=0;
                while (count==0){//网络请求可能为空
                    count=inputStream.available();
                }
                byte[] bytes=new byte[count];
                inputStream.read(bytes);
                System.out.println("____请求信息:\n"+new String(bytes));
                socket.close();
            }*/
            //静态资源
           /* while (true){
                Socket socket=serverSocket.accept() ;
                InputStream inputStream = socket.getInputStream();
                Request request=new Request(inputStream);
                Response response=new Response(socket.getOutputStream());
                response.outPut(request.getUrl());
                socket.close();
            }*/
            //动态资源
            while (true){
                Socket socket=serverSocket.accept() ;
                Runnable runnable=new RequestProcess(socket,servletMap);
                threadPoolExecutor.execute(runnable);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    private Map<String,HttpServlet> servletMap=new HashMap<>();
    /**
     * 解析文件
     */
    private void loadServlet() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
        SAXReader saxReader=new SAXReader();
        Document document = null;
        try {
            document = saxReader.read(resourceAsStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        Element rootElement = document.getRootElement();
        List<Element> nodes = rootElement.selectNodes("//servlet");
        for (int i = 0; i < nodes.size(); i++) {
            Element element=nodes.get(i);
            Element servletNameElement = (Element) element.selectSingleNode("servlet-name");
            String servletName=servletNameElement.getStringValue();
            Element servletClassElement= (Element) element.selectSingleNode("servlet-class");
            String servletClass=servletClassElement.getStringValue();
            //根据servletname 找到url
            Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
           //urlPattern
            String urlPattern  = servletMapping.selectSingleNode("url-pattern").getStringValue();
            servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());
        }
    }

    /**
     * 程序启动入口
     * @param args
     */
    public static void main(String[] args) {
        Bootstrap bootstrap=new Bootstrap();
        try {
            bootstrap.start();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
